package com.tuju.jetpackfirstdemo.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

import com.tuju.jetpackfirstdemo.ui.k.KBean;
import com.tuju.jetpackfirstdemo.utils.DensityUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class KLineView extends View {

    private List<Float> yData = Arrays.asList(0f, 200f, 400f);
    private List<String> xData = Arrays.asList("08:00", "09:00", "10:00", "11:00", "12:00"
            , "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00", "00:00", "01:00", "02:00", "03:00");
    private List<KBean.DataBean> mPointDatas = new ArrayList<>();

    public KLineView(Context context) {
        super(context);
        init();
    }

    public KLineView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public KLineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    //温度 设备
    private Paint mBulePaint;//蓝色曲线 温度
    private Paint mGreenPaint;//绿色曲线 设备
    private Paint mLinePaint;//画线
    private Paint mTxtPaint;//纵坐标文字
    private Paint dashPaint;//画线

    private void init() {
        Collections.reverse(yData);
        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mLinePaint.setColor(Color.parseColor("#CBCBCB"));
        mLinePaint.setStyle(Paint.Style.STROKE);
        mLinePaint.setStrokeWidth(DensityUtil.dip2px(1));

        mTxtPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTxtPaint.setColor(Color.parseColor("#505050"));
        mTxtPaint.setTextSize(DensityUtil.dip2px(12));

        mBulePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBulePaint.setColor(Color.parseColor("#3986F7"));
        mBulePaint.setStyle(Paint.Style.STROKE);
        mBulePaint.setStrokeWidth(DensityUtil.dip2px(2));
        mBulePaint.setStrokeCap(Paint.Cap.ROUND);
        mBulePaint.setStrokeJoin(Paint.Join.ROUND);

        mGreenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mGreenPaint.setColor(Color.parseColor("#5AB95A"));
        mGreenPaint.setStyle(Paint.Style.STROKE);
        mGreenPaint.setStrokeWidth(DensityUtil.dip2px(2));
        mGreenPaint.setStrokeCap(Paint.Cap.SQUARE);
        mGreenPaint.setStrokeJoin(Paint.Join.ROUND);

        //虚线画笔
        dashPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        dashPaint.setStyle(Paint.Style.STROKE);
//        dashPaint.setColor(Color.parseColor("#EFEFEF"));
        dashPaint.setColor(Color.parseColor("#000000"));
        dashPaint.setStrokeWidth(1);
        PathEffect effects = new DashPathEffect(new float[]{8, 8}, 0);
        dashPaint.setPathEffect(effects);
    }

    private float width;
    private float height;
    private float startX;//x轴开始宽度
    private float endX;//x轴最大宽度
    private float startY;//y轴开始高度
    private float endY;//y轴最大高度
    private float maxValueY;//所给Y轴最大值
    private float minValueY = 0;//所给Y轴最小值
    private long maxValueX;//所给X轴最大值
    private long minValueX;//所给X轴最小值
    private int textAngle = 60;//默认文字偏转角度

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        width = getWidth();//最大值 默认末尾间隔100像素
        height = getHeight();
        endX = width - dipToPx(30);
        startY = 0;

        //获取横坐标间隔
        float last0 = coverXValue(xData.get(0));
        float last1 = coverXValue(xData.get(1));
        float widthSpace = last1 - last0;
        endX = width - widthSpace;

        //获取横坐标文字最大宽度;
        float xTxtWidth = 0;
        for (int i = 0; i < xData.size(); i++) {
            xTxtWidth = Math.max(xTxtWidth, mTxtPaint.measureText(xData.get(i)));
        }
//        float xTxtHeight = (float) (xTxtWidth * Math.sin(Math.PI / 3));
        endY = height - xTxtWidth;
        //获取横坐标开始位置
        for (int i = 0; i < yData.size(); i++) {
            startX = Math.max(startX, mTxtPaint.measureText(yData.get(i) + ""));
        }
        startX += dipToPx(4);//加个间距

        //绘制纵坐标线和文字
        for (int i = 0; i < yData.size(); i++) {
            float yValue = coverYValue(yData.get(i));
            canvas.drawText(yData.get(i) + "", 0, yValue, mTxtPaint);
            Path path = new Path();
            if (yValue == endY) {
                path.moveTo(startX, endY);
                path.lineTo(endX, endY);
                canvas.drawPath(path, mLinePaint);
            } else {
                path.moveTo(startX, yValue - DensityUtil.dip2px(5));
                path.lineTo(endX, yValue - DensityUtil.dip2px(5));
                canvas.drawPath(path, dashPaint);
            }
        }

        //绘制横坐标文字与线段
        for (int i = 0; i < xData.size(); i++) {
            float xValue = coverXValue(xData.get(i));
            canvas.drawLine(xValue, endY, xValue, endY + 10, mLinePaint);
            Path path = new Path();
            path.moveTo(xValue, endY);
//            path.rLineTo(xTxtWidth,xTxtHeight);
            path.rLineTo(widthSpace, xTxtWidth);
            canvas.drawTextOnPath(xData.get(i), path, 10, 20, mTxtPaint);
        }

        //画折线
        Path bluePath = new Path();
        for (int i = 0; i < mPointDatas.size(); i++) {
            KBean.DataBean point = mPointDatas.get(i);
            float x = coverXValue(point.getX());
            float y = coverYValue(point.getY());
            if (i == 0) {
                bluePath.moveTo(x, y);
            } else {
                bluePath.lineTo(x, y);
            }
        }
        canvas.drawPath(bluePath, mBulePaint);

        //test
//        canvas.drawLine(100, 0, 100, endY,mBulePaint);
//        canvas.drawLine(140,endY,140,endY + xTxtHeight,mBulePaint);
        //尝试画贝塞尔曲线
        drawBezer(canvas);
    }

    //==============================*********贝塞尔曲线**********========================
    /** 即将要穿越的点集合 */
    private ArrayList<Point> mPoints;
    /** 中点集合 */
    private ArrayList<Point> mMidPoints;
    /** 中点的中点集合 */
    private ArrayList<Point> mMidMidPoints;
    /**
     * 移动后的点集合(控制点)
     */
    private ArrayList<Point> mAssistPoints;

    private void drawBezer(Canvas canvas) {

    }

    //将所给坐标转换为点
    private void reset() {
    }


    class Point{
        float x;
        float y;

        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public float getX() {
            return x;
        }

        public void setX(float x) {
            this.x = x;
        }

        public float getY() {
            return y;
        }

        public void setY(float y) {
            this.y = y;
        }
    }

    //==============================*********贝塞尔曲线end**********=====================

    /**
     * 根据所给value 求出做对应Y坐标
     */
    private float coverYValue(double value) {
        if (value == minValueY) {
            return endY;
        }
        double result = value * endY / maxValueY;
        return endY - (float) result;
    }

    /**
     * 根据所给value 求出做对应X坐标
     */
    private float coverXValue(String time) {
        long stamp = dateToStamp(time);
        if (stamp == minValueX) {
            return startX;
        }
        double result = (stamp - minValueX) * (endX - startX) / (maxValueX - minValueX) + startX;
        Log.i("yanze_coverXValue", "startX:" + startX + " endX:" + endX + " " + time + " " + stamp + " -> coverXValue: " + result);
        return (float) result;
    }

    public void setCoordinate(List<Float> yData, List<String> xTime, List<KBean.DataBean> pointData) {
        if (!yData.contains(0)) {
            yData.add(0f);
        }
        this.yData = yData;
        this.xData = xTime;
        this.mPointDatas = pointData;
        minValueY = yData.get(0);
        minValueX = dateToStamp(xTime.get(0));

        //确定x轴最大值与最小值
        for (int i = 0; i < xTime.size(); i++) {
            long timeValue = dateToStamp(xTime.get(i));
            maxValueX = Math.max(maxValueX, timeValue);
            minValueX = Math.min(minValueX, timeValue);
        }

        //确定y轴最大值与最小值
        for (int i = 0; i < yData.size(); i++) {
            maxValueY = Math.max(maxValueY, yData.get(i));
            minValueY = Math.min(minValueY, yData.get(i));
        }

        //查看一下点坐标 如果有更大的值则替换成坐标最大值
        for (int i = 0; i < pointData.size(); i++) {
            maxValueY = Math.max(maxValueY, pointData.get(i).getY());
            minValueY = Math.min(minValueY, pointData.get(i).getY());
            String timeStr = pointData.get(i).getX();
            maxValueX = Math.max(maxValueX, dateToStamp(timeStr));
            minValueX = Math.min(minValueX, dateToStamp(timeStr));
        }
        Log.i("yanze", "Y: " + " max: " + maxValueY + " min：" + minValueY);
        Log.i("yanze", "X: " + " max: " + maxValueX + "(" + stampToDate(maxValueX) + ")" + " min：" + minValueX + "(" + stampToDate(minValueX) + ")");
        invalidate();
    }

    /**
     * dip 转换成px
     *
     * @param dip
     * @return
     */
    private int dipToPx(float dip) {
        float density = getContext().getResources().getDisplayMetrics().density;
        return (int) (dip * density + 0.5f * (dip >= 0 ? 1 : -1));
    }

    /*
     * 将时间转换为时间戳
     */
    public static long dateToStamp(String oldS) {
        String s = oldS.replace("T", " ");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
        } catch (ParseException e) {
            return 0;
        }
        long ts = date.getTime();
        return ts;
    }

    /*
     * 将时间戳转换为时间
     */
    public static String stampToDate(long s) {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date(s);
        res = simpleDateFormat.format(date);
        return res;
    }
}
